/********************************************************************************
* @file    bsp_pwm.c
* @author  jianqiang.xue
* @version V1.0.0
* @date    2021-08-10
* @brief   参考：https://blog.csdn.net/zhi_Alanwu/article/details/102972721
********************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include <stdbool.h>
#include <stdint.h>

#include "RTE_Components.h"
#include CMSIS_device_header
#include "app_pwm.h"

#include "bsp_gpio.h"
#include "bsp_pwm.h"

/* Private Includes ----------------------------------------------------------*/
#include "ls_gpio.h"
#include "ls_syscfg.h"

/* Private Variables ---------------------------------------------------------*/
static bool g_pwm_init = false;

#if BS_TIM1_EN
// Create the instance "PWM1" using TIMER1.
APP_PWM_INSTANCE(PWM1, 1);
/* 2-channel PWM*/
static const app_pwm_config_t pwm1_cfg =
{
    .pins            = {BS_TIM1_CH1_PIN, BS_TIM1_CH2_PIN},
    .pin_polarity    = {(app_pwm_polarity_t)BS_TIM1_LEVEL_LOGIC, (app_pwm_polarity_t)BS_TIM1_LEVEL_LOGIC},
    .num_of_channels = 2,
    .period_us       = BS_TIM1_PRESCALER,
};
#endif

#if BS_TIM2_EN
// Create the instance "PWM2" using TIMER2.
APP_PWM_INSTANCE(PWM2, 2);
/* 2-channel PWM*/
static const app_pwm_config_t pwm2_cfg =
{
    .pins            = {BS_TIM2_CH1_PIN, BS_TIM2_CH2_PIN},
    .pin_polarity    = {(app_pwm_polarity_t)BS_TIM2_LEVEL_LOGIC, (app_pwm_polarity_t)BS_TIM2_LEVEL_LOGIC},
    .num_of_channels = 2,
    .period_us       = BS_TIM2_PRESCALER,
};
#endif

/* Public Function Prototypes -----------------------------------------------*/
/**
 * @brief  PWN功能初始化，使用定时器和ppi来模拟PWM功能
 */
void bsp_pwm_init(void)
{
    if (g_pwm_init)
    {
        return;
    }

#if BS_TIM1_EN
    /* Initialize and enable PWM. */
    APP_ERROR_CHECK(app_pwm_init(&PWM1, &pwm1_cfg, NULL));
    app_pwm_enable(&PWM1);
    g_pwm_init = true;
#endif

#if BS_TIM2_EN
    /* Initialize and enable PWM. */
    APP_ERROR_CHECK(app_pwm_init(&PWM2, &pwm2_cfg, NULL));
    app_pwm_enable(&PWM2);
    g_pwm_init = true;
#endif
}

/**
 * @brief  PWN功能关闭
 * @note   NULL
 * @retval None
 */
void bsp_pwm_deinit(void)
{
    if (!g_pwm_init)
    {
        return;
    }
#if BS_TIM1_EN
    app_pwm_disable(&PWM1);
    app_pwm_uninit(&PWM1);
    g_pwm_init = false;
#endif
#if BS_TIM2_EN
    app_pwm_disable(&PWM2);
    app_pwm_uninit(&PWM2);
    g_pwm_init = false;
#endif
}

/**
 * @brief  设置PWM占空比
 * @param  pwmx: PWM组号
 * @param  val: 0-100 PWM值
 */
void bsp_pwm_set_pulse(bsp_pwm_t pwmx, uint16_t val)
{
#if BS_TIM1_EN || BS_TIM2_EN
    if (!g_pwm_init)
    {
        return;
    }
#endif
    if (pwmx == BSP_PWM_0)
    {
#if BS_TIM1_EN && BS_PWM0_EN
        app_pwm_channel_duty_set(&PWM1, 0, val);
#endif
    }
    else if (pwmx == BSP_PWM_1)
    {
#if BS_TIM1_EN && BS_PWM1_EN
        app_pwm_channel_duty_set(&PWM1, 1, val);
#endif
    }
    else if (pwmx == BSP_PWM_4)
    {
#if BS_TIM2_EN && BS_PWM4_EN
        app_pwm_channel_duty_set(&PWM2, 0, val);
#endif
    }
    else if (pwmx == BSP_PWM_5)
    {
#if BS_TIM2_EN && BS_PWM5_EN
        app_pwm_channel_duty_set(&PWM2, 1, val);
#endif
    }
}
